package com.zy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.bean.bo.project.ProjectCreateBo;
import com.zy.bean.bo.project.ProjectUpdateBo;
import com.zy.bean.po.ProjectRecords;
import com.zy.bean.qo.ProjectSearchQo;
import com.zy.bean.vo.FlowChartVo;
import com.zy.bean.vo.ProjectRecordsVo;
import com.zy.config.SpringContextHolder;
import com.zy.mapper.ProjectRecordsMapper;
import com.zy.service.ChartRecordsService;
import com.zy.service.ProjectRecordsService;
import com.zy.util.SnowflakeIdWorker;
import com.zy.util.UserUtil;
import com.zy.util.VersionUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

import static org.fatewa.engine.genius.utils.GenericUtils.transaction;

/**
 * @author hanhuafeng
 * @createDate 2023-05-31 15:37:36
 * @description 项目管理表
 */
@Service
@RequiredArgsConstructor
public class ProjectRecordsServiceImpl extends ServiceImpl<ProjectRecordsMapper, ProjectRecords>
        implements ProjectRecordsService {
    private final VersionUtil versionUtil;
    private final UserUtil userUtil;
    private final ChartRecordsService chartRecordsService;

    /**
     * 创建项目
     *
     * @param projectCreateBo 项目创建bo
     * @return ProjectRecords
     */
    @Override
    public ProjectRecords createProjectRecords(ProjectCreateBo projectCreateBo) {
        ProjectRecords project = new ProjectRecords();
        String projectCode = SnowflakeIdWorker.getUuid();
        project.setProjectCode(projectCode);
        project.setName(projectCreateBo.getName());
        project.setCreateUserId(userUtil.getUserCode());
        this.save(project);
        return project;
    }

    /**
     * 分页获取项目列表
     *
     * @param qo 查询条件
     * @return Page<ProjectRecordsVo>
     */
    @Override
    public Page<ProjectRecordsVo> getProjectRecordsByPage(ProjectSearchQo qo) {
        Page<ProjectRecordsVo> result = new Page<>(qo.getCurrent(), qo.getSize());
        LambdaQueryWrapper<ProjectRecords> lqw = new LambdaQueryWrapper<>();
        lqw.like(ObjectUtils.isNotEmpty(qo.getProjectName()), ProjectRecords::getName, qo.getProjectName());
        lqw.like(ObjectUtils.isNotEmpty(qo.getProjectCode()), ProjectRecords::getProjectCode, qo.getProjectCode());
        Page<ProjectRecords> pageResult = this.page(qo.getPage(), lqw);
        if (ObjectUtils.isEmpty(pageResult.getRecords())) {
            return result;
        }
        List<ProjectRecordsVo> voList = new LinkedList<>();
        pageResult.getRecords().forEach(project -> {
            ProjectRecordsVo vo = new ProjectRecordsVo();
            vo.setProjectCode(project.getProjectCode());
            vo.setProjectName(project.getName());
            vo.setChartList(chartRecordsService.getChartRecordsByProjectCode(project.getProjectCode()));
            voList.add(vo);
        });
        result.setRecords(voList);
        result.setTotal(pageResult.getTotal());
        return result;
    }

    /**
     * 根据项目code修改项目信息
     *
     * @param projectCode     项目code
     * @param projectUpdateBo 项目修改bo
     * @return ProjectRecords
     */
    @Override
    public ProjectRecords updateProjectRecords(String projectCode, ProjectUpdateBo projectUpdateBo) {
        ProjectRecords project = this.getProjectRecordsByProjectCode(projectCode);
        if (ObjectUtils.isEmpty(project)) {
            throw new IllegalArgumentException("项目不存在");
        }
        project.setName(projectUpdateBo.getName());
        this.updateById(project);
        return project;
    }

    @Override
    public void deleteProject(String projectCode) {
        transaction((manager, status) -> {
            LambdaQueryWrapper<ProjectRecords> lqw = new LambdaQueryWrapper<>();
            lqw.eq(ProjectRecords::getProjectCode, projectCode);
            this.remove(lqw);
            // 获取下方的所有流程图的code
            List<String> chartRecordsByProjectCode = chartRecordsService.getChartRecordsByProjectCode(projectCode).stream().map(FlowChartVo::getCode).toList();
            // 删除下面的流程图
            chartRecordsService.deleteChartRecordsByProjectCode(projectCode);
            if (ObjectUtils.isNotEmpty(chartRecordsByProjectCode)) {
                versionUtil.deleteVersionByProjectCode(chartRecordsByProjectCode);
            }
        }, SpringContextHolder.getApplicationContext());
    }

    /**
     * 根据项目code获取项目信息
     *
     * @param projectCode 项目code
     * @return ProjectRecordsVo 项目信息
     */
    @Override
    public ProjectRecordsVo getProjectRecordsByCode(String projectCode) {
        ProjectRecords project = this.getProjectRecordsByProjectCode(projectCode);
        if (ObjectUtils.isNotEmpty(project)) {
            ProjectRecordsVo vo = new ProjectRecordsVo();
            vo.setProjectCode(project.getProjectCode());
            vo.setProjectName(project.getName());
            return vo;
        }
        return null;
    }

    /**
     * 根据项目code获取项目信息
     *
     * @param projectCode 项目code
     * @return ProjectRecords
     */
    private ProjectRecords getProjectRecordsByProjectCode(String projectCode) {
        if (ObjectUtils.isEmpty(projectCode)) {
            throw new IllegalArgumentException("项目code不能为空");
        }
        LambdaQueryWrapper<ProjectRecords> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ProjectRecords::getProjectCode, projectCode);
        return this.getOne(lqw);
    }
}




